//@author A0083782W
//Time is a class which creates an object that stores time.
//Currently it only has a set and get function
//Set and get is specified by GetTimeFunctions::TimeType
//E.g. Create a time object named newTime:
//Time newTime;
//Set the time stored in newTime to be 9/2/2014 9:15 am, 
//you can do the following:
//newTime.setTime(TimeType::DAY,9);
//newTime.setTime(TimeType::MONTH 2);
//...etc.
//Same applies to get.
//Waiting for shitong to finish the weekday function
//
//For the overload operators, this class can be compared with each other using
//== != > < <= >= |= &=
//Note: A later time is considered larger
//|= : see if two Time objects have equal time portion
//&= : see if two Time objects have equal date portion
//-- ++ will be able to decrease or increase the date by 1 day
//= is able to match a Time object to CurrentTime object
//= is able to copy two Time object
//
//If the input data is obviously wrong, then the data inside the class will 
//not be changed to protect the data
//If the input data is potentially wrong but the class not able to determine now,
//then the isLastInputLegal is able to capture the wrongness later
//Also, wrong data input in this way will be automatically fixed.


#pragma once 

#include "ConstantList.h"
#include "TECommonFunctions.h"
#include "UserCommandEnum.h"
#include "CurrentTime.h"
#include "Settings.h"
#include <string>

using CommonDataType::ByteInt;
using CommonDataType::pos_int;
using GetCurrentTimeFunctions::TimeType;
using namespace TimeManipulator;
using std::string;
using std::to_string;
using namespace TimeConstants;
using StringManipulator::capitaliseFirst;

class Time {
	
public:
	const static ByteInt TIME_MAX = 8;
	const static ByteInt FIRST_MEMBER = 1;
	Time();
	Time(const Time& anotherTime);

	static bool canBeSet (TimeType requiredType, ByteInt newValue);
	bool setTime (TimeType requiredType, ByteInt newValue);
	ByteInt getTime (TimeType requiredType) const;
	bool isLastInputLegal () const;
	bool isSecondDisplayable() const;
	void setSecondDisplay(bool newBool);
	bool isCompletedDate() const;
	bool isEmpty() const;

	bool operator == (const Time& rightOperand) const;
	bool operator < (const Time& rightOperand) const;
	bool operator > (const Time& rightOperand) const;
	bool operator >= (const Time& rightOperand) const;
	bool operator <= (const Time& rightOperand) const;
	bool operator != (const Time& rightOperand) const;

	//Check if the time part the Time class is equal
	bool operator |= (const Time& rightOperand) const;

	//Check if the date part of the time is equal
	bool operator &= (const Time& rightOperand) const;

	//Going up for 1day
	void operator ++ (int);

	//Going down for 1day
	void operator -- (int);
	void operator = (const CurrentTime& rightOperand);

	string toDateString() const;
	string toTimeString() const;
	string toDayOfWeekString() const;

	void reset();

protected:
	bool _lastSet;
	bool _secondDisplayable;
	ByteInt timeData[TIME_MAX];
	void generateDayOfWeek();
	bool checkAndFixDate();
};

//put 2 to 02, fix the display length to be 2.
static string standardisedString(const string& mainString);
